#pragma once

#include "base_types.h"
#include <functional>
#include <memory>
#include <chrono>
#include <map>

// Timer callback type
using TimerCallback = std::function<void(int timer_id)>;

// Timer event interface
class TimerOutEvent {
public:
    TimerOutEvent() = default;
    virtual ~TimerOutEvent() = default;
    
    // Timer timeout handler
    virtual int ProcessOnTimerOut(int timer_id) = 0;
};

// Timer class
class CCTimer {
public:
    CCTimer();
    ~CCTimer();
    
    // Start timer
    int Start(int timeout_ms, TimerCallback callback);
    int Start(int timeout_ms, TimerOutEvent* event_handler);
    
    // Stop timer
    int Stop();
    
    // Check if timer is active
    bool IsActive() const { return timer_id != -1; }
    
    // Get timer ID
    int GetTimerId() const { return timer_id; }
    
    // Update timer (for recurring timers)
    int Update(int new_timeout_ms);
    
private:
    int timer_id;
    TimerCallback callback;
    TimerOutEvent* event_handler;
    bool is_callback; // true if using callback, false if using event handler
};

// Timer manager
class CTimerManager {
public:
    static CTimerManager& Instance();
    
    // Add timer
    int AddTimer(int timeout_ms, TimerCallback callback);
    int AddTimer(int timeout_ms, TimerOutEvent* event_handler);
    
    // Remove timer
    int RemoveTimer(int timer_id);
    
    // Update timer
    int UpdateTimer(int timer_id, int new_timeout_ms);
    
    // Process expired timers
    void ProcessTimers();
    
    // Get next timeout
    int GetNextTimeout() const;
    
private:
    CTimerManager() = default;
    ~CTimerManager() = default;
    
    struct TimerInfo {
        int timer_id;
        int timeout_ms;
        std::chrono::steady_clock::time_point next_timeout;
        TimerCallback callback;
        TimerOutEvent* event_handler;
        bool is_callback;
        bool recurring;
    };
    
    int next_timer_id;
    std::map<int, TimerInfo> timers;
    
    int GenerateTimerId();
};

// Global timer manager instance
extern CTimerManager* g_timer_manager;